package com.rt.web.controller.system;

import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.rt.common.utils.StringUtils;
import com.rt.common.utils.file.ImageUtils;
import com.rt.common.utils.poi.ExcelUtil;
import com.rt.system.domain.*;
import com.rt.system.service.IRtAssemblyInfoService;
import com.rt.system.service.IRtQuestionTypeService;
import com.rt.system.service.IRtQuestionsInfoService;
import com.rt.system.service.impl.RtQuestionsInfoServiceImpl;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.rt.common.annotation.Log;
import com.rt.common.core.controller.BaseController;
import com.rt.common.core.domain.AjaxResult;
import com.rt.common.enums.BusinessType;
import com.rt.system.service.IRtExamPaperInfoService;
import com.rt.common.core.page.TableDataInfo;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

/**
 * 试卷信息Controller
 * 
 * @author Yg
 * @date 2022-05-09
 */
@RestController
@RequestMapping("/system/paper")
public class RtExamPaperInfoController extends BaseController
{
    @Autowired
    private IRtExamPaperInfoService rtExamPaperInfoService;

    @Autowired
    private IRtAssemblyInfoService rtAssemblyInfoService;

    @Autowired
    private IRtQuestionTypeService rtQuestionTypeService;

    /**
     * 查询试卷信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:paper:list')")
    @GetMapping("/list")
    public TableDataInfo list(RtExamPaperInfo rtExamPaperInfo)
    {
        startPage();
        List<RtExamPaperInfo> list = rtExamPaperInfoService.selectRtExamPaperInfoList(rtExamPaperInfo);
        return getDataTable(list);
    }

    /**
     * 查询试卷查重
     */
    @GetMapping(value = "/duplicateList/{id}")
    public TableDataInfo duplicateList(@PathVariable("id") Long id)
    {
        List<RtQuestionsInfo> list = rtExamPaperInfoService.selectRtExamPaperDuplicateList(id);
        return getDataTable(list);
    }


    /**
     * 导出试卷信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:paper:export')")
    @Log(title = "试卷信息", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public void export(RtExamPaperInfo rtExamPaperInfo, HttpServletResponse response) throws IOException, InvalidFormatException {
        // 查询试卷试题列表
        List<RtQuestionsInfo> rtQuestionsInfos=rtExamPaperInfoService.selectRtExamQyestinsInfoList(rtExamPaperInfo.getId());
        // 试卷
        RtExamPaperInfo rtExamPaperInfo1 = rtExamPaperInfoService.selectRtExamPaperInfoById(rtExamPaperInfo.getId());
        // 试卷策略
        RtAssemblyInfo rtAssemblyInfo = rtAssemblyInfoService.selectRtAssemblyInfoById(rtExamPaperInfo1.getAssemblyId());
        createWord2007(rtQuestionsInfos,rtAssemblyInfo,rtExamPaperInfo1.getPaperName(),response);
    }

    /**
     *  批量导出导出试卷信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:paper:export')")
    @Log(title = "试卷信息", businessType = BusinessType.EXPORT)
    @GetMapping("/export/{ids}")
    public void batchexport(@PathVariable Long[] ids, HttpServletResponse response) throws IOException, InvalidFormatException {
        // 查询试卷试题列表
        List<RtQuestionsInfo> rtQuestionsInfos=rtExamPaperInfoService.selectRtExamQyestinsInfoListIds(ids);
        // 试卷
        batchexport(rtQuestionsInfos,"汇总导出",response);
    }

//    @Log(title = "导出答案", businessType = BusinessType.EXPORT)
    @GetMapping( "/exportExcle/{ids}")
    public AjaxResult exportExcle(@PathVariable Long[] ids)
    {
        List<RtExamPaper> list = rtExamPaperInfoService.selectRtExamQyestinsInfoListExcle(ids);
        ExcelUtil<RtExamPaper> util = new ExcelUtil<RtExamPaper>(RtExamPaper.class);
        return util.exportExcel(list, "试卷导出");
    }

    /**
     * 导出答案
     */
    @PreAuthorize("@ss.hasPermi('system:paper:export')")
    @Log(title = "导出答案", businessType = BusinessType.EXPORT)
    @GetMapping("/exportAnswer")
    public void answerExport(RtExamPaperInfo rtExamPaperInfo, HttpServletResponse response) throws IOException, InvalidFormatException {
        // 查询试卷试题列表
        List<RtQuestionsInfo> rtQuestionsInfos=rtExamPaperInfoService.selectRtExamQyestinsInfoList(rtExamPaperInfo.getId());
        // 试卷
        RtExamPaperInfo rtExamPaperInfo1 = rtExamPaperInfoService.selectRtExamPaperInfoById(rtExamPaperInfo.getId());
        // 试卷策略
        RtAssemblyInfo rtAssemblyInfo = rtAssemblyInfoService.selectRtAssemblyInfoById(rtExamPaperInfo1.getAssemblyId());
        answerExport(rtQuestionsInfos,rtAssemblyInfo,rtExamPaperInfo1.getPaperName(),response);
    }

    // word 构建
    public void answerExport(List<RtQuestionsInfo> rtQuestionsInfos, RtAssemblyInfo rtAssemblyInfo, String paperName, HttpServletResponse response) throws IOException, InvalidFormatException {
        String[] numb = {"一","二","三","四","五"};
        // 小题序号
        Integer count=0;
        // 模块与题型序号
        Integer typeNum=0;
        // 创建Word文件
        XWPFDocument doc = new XWPFDocument();
        // 新建一个段落
        XWPFParagraph p = doc.createParagraph();
        // 设置段落的对齐方式
        p.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = p.createRun();
        // 试卷名称
        run.setText(paperName);
        run.setFontSize(20);
        run.setBold(true);
        for (RtAssemblyConf rtAssemblyConf : rtAssemblyInfo.getRtAssemblyConfs()) {
            p = doc.createParagraph();
            run = p.createRun();
            run.setText(numb[typeNum]+"、"+rtAssemblyConf.getQuestionType()+"(共"+rtAssemblyInfoService.selectRtAssemblyConfigCount(rtAssemblyConf.getQuestionTypeId(),rtAssemblyInfo.getId())+"题，每题"+rtAssemblyConf.getSingleScore()+"分)");
            run.setFontSize(15);
            run.setBold(true);
            typeNum++;
            for (RtQuestionsInfo rtQuestionsInfo : rtQuestionsInfos) {
                if (StringUtils.isNull(rtAssemblyConf.getQuestionTypeModuleId())?(rtAssemblyConf.getQuestionTypeId().equals(rtQuestionsInfo.getQuestionTypeId())&& StringUtils.isNull(rtQuestionsInfo.getQuestionModuleId())):(rtAssemblyConf.getQuestionTypeId().equals(rtQuestionsInfo.getQuestionTypeId())&& rtAssemblyConf.getQuestionTypeModuleId().equals(rtQuestionsInfo.getQuestionModuleId()))){
                    if (rtAssemblyConf.getQuestionTypeId()==5){
                        // 循环拿案例下小题
                        for (RtQuestionsInfo questionsInfo : rtQuestionsInfo.getRtQuestionsInfos()) {
                            count++;
                            answer(doc,questionsInfo,count);
                        }
                    }else {
                        count++;
                        answer(doc,rtQuestionsInfo,count);
                    }
                }
            }
        }
//        FileOutputStream out;
        try {
//            out = new FileOutputStream("D:/word2007.docx");
//             以下代码可进行文件下载
            response.reset();
            //强制下载不打开
            response.setContentType("application/force-download");
            OutputStream out = response.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("试题答案生成", "UTF-8"));
            doc.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void answer(XWPFDocument doc,RtQuestionsInfo rtQuestionsInfo,Integer count){
        String[] opt = {"A","B","C","D","E","F","G","H","I","J"};
        XWPFParagraph p = doc.createParagraph();// 新建一个段落
        XWPFRun run = p.createRun();
        run.setFontSize(12);
        // 单选 多选 简答 判断的方法
        run.setText(count+". ");
        if (rtQuestionsInfo.getQuestionTypeId()==1 || rtQuestionsInfo.getQuestionTypeId()==2){
            for (int i = 0; i < rtQuestionsInfo.getRtOptionsInfos().size(); i++) {
                if (rtQuestionsInfo.getRtOptionsInfos().get(i).getIsAnswer()==1){
                    run.setText(opt[i]+" ");
                }
            }
        }
        if (rtQuestionsInfo.getQuestionTypeId()==4){
            if (rtQuestionsInfo.getIsCorrect()==1){
                run.setText("正确");
            }else {
                run.setText("错误");
            }
        }
        if (rtQuestionsInfo.getQuestionTypeId()==6){
            run.setText(rtQuestionsInfo.getAnswer().replaceAll("<[.[^<]]*>", ""));
        }
    }

    // 试卷word 构建
    public void batchexport(List<RtQuestionsInfo> rtQuestionsInfos, String paperName, HttpServletResponse response) throws IOException, InvalidFormatException {
        String[] opt = {"A","B","C","D","E","F","G","H","I","J"};
        String[] numb = {"一","二","三","四","五","六","七","八","九","十","十一","十二","十三","十四","十五","十六","十七","十八","十九"};
        // 小题序号
        Integer count=0;
        // 判断是否是相同题型
        Long typeId=0L;
        // 模块与题型序号
        Integer typeNum=0;
        // 创建Word文件
        XWPFDocument doc = new XWPFDocument();
        // 新建一个段落
        XWPFParagraph p = doc.createParagraph();
        // 设置段落的对齐方式
        p.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = p.createRun();
        // 试卷名称
        run.setText(paperName);
        run.setFontSize(20);
        run.setBold(true);
        for (RtQuestionsInfo rtQuestionsInfo : rtQuestionsInfos) {
            if (rtQuestionsInfo.getQuestionTypeId()!=typeId){
                // 新建一个段落
                p = doc.createParagraph();
                run = p.createRun();
                run.setText(numb[typeNum]+"、"+rtQuestionTypeService.selectRtQuestionTypeById(rtQuestionsInfo.getQuestionTypeId()).getName());
                run.setFontSize(15);
                run.setBold(true);
                typeNum++;
            }
            if (rtQuestionsInfo.getQuestionTypeId()==5){
                // 案列题背景材料
                p = doc.createParagraph();
                run = p.createRun();
                run.setText("材料背景:"+rtQuestionsInfo.getQuestionsContent().replaceAll("<[.[^<]]*>", ""));
                run.setFontSize(10);
                // 循环拿案例下小题
                for (RtQuestionsInfo questionsInfo : rtQuestionsInfo.getRtQuestionsInfos()) {
                    count++;
                    universal(doc,questionsInfo,count,opt);
                }
            }else {
                count++;
                // 单选 多选 简答 判断的方法
                universal(doc,rtQuestionsInfo,count,opt);
            }
            typeId=rtQuestionsInfo.getQuestionTypeId();
        }
//        FileOutputStream out;
        try {
//            out = new FileOutputStream("D:/word2007.docx");
//             以下代码可进行文件下载
            response.reset();
            //强制下载不打开
            response.setContentType("application/force-download");
            OutputStream out = response.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("试卷生成", "UTF-8"));
            doc.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 试卷word 构建
    public void createWord2007(List<RtQuestionsInfo> rtQuestionsInfos, RtAssemblyInfo rtAssemblyInfo, String paperName, HttpServletResponse response) throws IOException, InvalidFormatException {
        String[] opt = {"A","B","C","D","E","F","G","H","I","J"};
        String[] numb = {"一","二","三","四","五","六","七","八","九","十","十一","十二","十三","十四","十五","十六","十七","十八","十九"};
        // 小题序号
        Integer count=0;
        // 判断是否是相同题型
        Long typeId=0L;
        // 模块与题型序号
        Integer moduleNum=0;
        Integer typeNum=0;
        // 创建Word文件
        XWPFDocument doc = new XWPFDocument();
        // 新建一个段落
        XWPFParagraph p = doc.createParagraph();
        // 设置段落的对齐方式
        p.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = p.createRun();
        // 试卷名称
        run.setText(paperName);
        run.setFontSize(20);
        run.setBold(true);
        for (RtAssemblyConf rtAssemblyConf : rtAssemblyInfo.getRtAssemblyConfs()) {
            if (rtAssemblyConf.getQuestionTypeId()!=typeId){
                // 新建一个段落
                p = doc.createParagraph();
                run = p.createRun();
                run.setText(numb[moduleNum]+"、"+rtAssemblyConf.getQuestionType()+"(共"+rtAssemblyInfoService.selectRtAssemblyConfigCount(rtAssemblyConf.getQuestionTypeId(),rtAssemblyInfo.getId())+"题，每题"+rtAssemblyConf.getSingleScore()+"分)");
                run.setFontSize(15);
                run.setBold(true);
                // 重置模块顺序
                typeNum=0;
                moduleNum++;
            }
            if (StringUtils.isNotNull(rtAssemblyConf.getQuestionTypeModuleId())){
                p = doc.createParagraph();
                run = p.createRun();
                run.setText("("+numb[typeNum]+")、"+rtAssemblyConf.getQuestionTypeModule());
                run.setFontSize(12);
                run.setBold(true);
                typeNum++;
            }
            for (RtQuestionsInfo rtQuestionsInfo : rtQuestionsInfos) {
                if (StringUtils.isNull(rtAssemblyConf.getQuestionTypeModuleId())?(rtAssemblyConf.getQuestionTypeId().equals(rtQuestionsInfo.getQuestionTypeId())&& StringUtils.isNull(rtQuestionsInfo.getQuestionModuleId())):(rtAssemblyConf.getQuestionTypeId().equals(rtQuestionsInfo.getQuestionTypeId())&& rtAssemblyConf.getQuestionTypeModuleId().equals(rtQuestionsInfo.getQuestionModuleId()))){
                    if (rtAssemblyConf.getQuestionTypeId()==5){
                        // 案列题背景材料
                        p = doc.createParagraph();
                        run = p.createRun();
                        run.setText("材料背景:"+rtQuestionsInfo.getQuestionsContent().replaceAll("<[.[^<]]*>", ""));
                        run.setFontSize(10);
                        // 循环拿案例下小题
                        for (RtQuestionsInfo questionsInfo : rtQuestionsInfo.getRtQuestionsInfos()) {
                            count++;
                            universal(doc,questionsInfo,count,opt);
                        }
                    }else {
                        count++;
                        // 单选 多选 简答 判断的方法
                        universal(doc,rtQuestionsInfo,count,opt);
                    }
                }
            }
            typeId=rtAssemblyConf.getQuestionTypeId();
        }
//        FileOutputStream out;
        try {
//            out = new FileOutputStream("D:/word2007.docx");
//             以下代码可进行文件下载
            response.reset();
            //强制下载不打开
            response.setContentType("application/force-download");
            OutputStream out = response.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode("试卷生成", "UTF-8"));
            doc.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void universal(XWPFDocument doc,RtQuestionsInfo rtQuestionsInfo,Integer count,String[] opt) throws IOException, InvalidFormatException {
        XWPFParagraph p = doc.createParagraph();// 新建一个段落
        XWPFRun run = p.createRun();
        // 图片
        getImgStr(rtQuestionsInfo.getQuestionsContent(),doc);
        // 清除格式
        if (rtQuestionsInfo.getQuestionTypeId()==5){
            run.setText(rtQuestionsInfo.getQuestionsContent().replaceAll("<[.[^<]]*>", ""));
        }else {
            run.setText(count+"."+rtQuestionsInfo.getQuestionsContent().replaceAll("<[.[^<]]*>", ""));
        }
        if (rtQuestionsInfo.getQuestionTypeId()==1||rtQuestionsInfo.getQuestionTypeId()==2){
            choose(rtQuestionsInfo,opt,doc);
        }
        if (rtQuestionsInfo.getQuestionTypeId()==4){
            p = doc.createParagraph();
            run = p.createRun();
            run.setText("A.对");
            if (rtQuestionsInfo.getIsCorrect()==1){
                run.setColor("FF0000");
            }
            p = doc.createParagraph();
            run = p.createRun();
            run.setText("B.错");
            if (rtQuestionsInfo.getIsCorrect()==0){
                run.setColor("FF0000");
            }
        }
    }

    // 单选与多选
    public void choose(RtQuestionsInfo rtQuestionsInfo,String[] opt,XWPFDocument doc) throws IOException, InvalidFormatException {
        for (int i = 0; i < rtQuestionsInfo.getRtOptionsInfos().size(); i++) {
            XWPFParagraph p = doc.createParagraph();// 新建一个段落
            XWPFRun run = p.createRun();
            getImgStr(rtQuestionsInfo.getRtOptionsInfos().get(i).getRemark(),doc);
            // 清除格式
            run.setText(opt[i]+". "+rtQuestionsInfo.getRtOptionsInfos().get(i).getRemark().replaceAll("<[.[^<]]*>", ""));
            if (rtQuestionsInfo.getRtOptionsInfos().get(i).getIsAnswer()==1){
                run.setColor("FF0000");
            }
        }
    }

    public static List<String> getImgStr(String htmlStr,XWPFDocument doc) throws IOException, InvalidFormatException {
        List<String> list = new ArrayList<>();
        String img = "";
        Pattern p_image;
        Matcher m_image;
        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            // 得到<img />数据
            img = m_image.group();
            // 匹配<img>中的src数据
            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
            while (m.find()) {
                list.add(m.group(1));
            }
        }
        if (StringUtils.isNotNull(list)){
            for (String s : list) {
                XWPFParagraph p = doc.createParagraph();// 新建一个段落
                XWPFRun run = p.createRun();
                InputStream file = ImageUtils.getFile(s);
                BufferedImage sourceImg = ImageIO.read(file);
                run.addPicture(ImageUtils.getFile(s),5,"测试", Units.toEMU(sourceImg.getWidth() * (21/29.7)),Units.toEMU(sourceImg.getHeight() * (21/29.7)));
            }
        }
        return list;
    }
    /**
     * 获取试卷信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:paper:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(rtExamPaperInfoService.selectRtExamPaperInfoById(id));
    }

    /**
     * 新增试卷信息
     */
    @PreAuthorize("@ss.hasPermi('system:exampaper:add')")
    @Log(title = "试卷信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody RtExamPaperInfo rtExamPaperInfo)
    {
        return toAjax(rtExamPaperInfoService.insertRtExamPaperInfo(rtExamPaperInfo));
    }

    /**
     * 修改试卷信息
     */
    @PreAuthorize("@ss.hasPermi('system:paper:edit')")
    @Log(title = "试卷信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody RtExamPaperInfo rtExamPaperInfo)
    {
        return toAjax(rtExamPaperInfoService.updateRtExamPaperInfo(rtExamPaperInfo));
    }

    /**
     * 发布试卷信息
     */
    @Log(title = "试卷信息发布", businessType = BusinessType.UPDATE)
    @PutMapping("/release")
    public AjaxResult release(@RequestBody RtExamPaperInfo rtExamPaperInfo)
    {
        return toAjax(rtExamPaperInfoService.releaseRtExamPaperInfo(rtExamPaperInfo));
    }

    /**
     * 删除试卷信息
     */
    @PreAuthorize("@ss.hasPermi('system:paper:remove')")
    @Log(title = "试卷信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(rtExamPaperInfoService.deleteRtExamPaperInfoByIds(ids));
    }
}
